home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / c / cpptask1.zip / TASK.H < prev    next >
C/C++ Source or Header  |  1991-02-07  |  5KB  |  189 lines

  1. /**********************************************************************
  2.  *  
  3.  *  NAME:           task.h
  4.  *  
  5.  *  DESCRIPTION:    modified version of Bruce Eckel's C++ task manager
  6.  *                  from Computer Language Feb. 1991
  7.  *  
  8.  *                  note that the variable naming conventions are somewhat
  9.  *                  "Hungarian" in nature, but not so as to be unreadable
  10.  *
  11.  *  M O D I F I C A T I O N   H I S T O R Y
  12.  *
  13.  *  when        who                 what
  14.  *  -------------------------------------------------------------------
  15.  *  02/04/91    J. Alan Eldridge    created
  16.  *
  17.  *  02/05/91    JAE                 modified so it would run: made each
  18.  *                                  task have its own stack to eliminate
  19.  *                                  the stack copying (which is not only
  20.  *                                  ugly and limiting, but dangerous as well)
  21.  *  
  22.  *                                  added semaphores for task waiting
  23.  *
  24.  * 02/07/91     JAE                 changed from arrays of tasks, semas to
  25.  *                                  singly linked list
  26.  *
  27.  *********************************************************************/
  28.  
  29. #ifndef __TASK_H
  30. #define __TASK_H    1
  31.  
  32. #ifndef __AEDEF_H
  33. #include    "aedef.h"
  34. #endif
  35.  
  36. //  fatal error handler (this never returns)
  37. extern void tskFatal(char *fmt, ...);
  38.  
  39. //  this is the base class, since we need lists of both
  40. //  Tasks and Semas, but want only one type of list
  41.  
  42. class TskObj {
  43. private:
  44.  
  45.     TskObj  *link;              //  link to next object in list
  46. public:
  47.  
  48.     TskObj(): link(0)
  49.         { }
  50.     virtual ~TskObj()
  51.         { }
  52.         
  53.     TskObj  *next()             //  return ptr to next object
  54.         { return link; }
  55.     void    linkTo(TskObj *o)   //  set ptr to next object
  56.         { link = o; }
  57. };
  58.  
  59. class TskList {
  60. private:
  61.  
  62.     int     cObj;       //  count of objects
  63.     TskObj  *pHead,     //  ptr to first on list
  64.             *pTail;     //  ptr to last on list
  65.  
  66. public:
  67.  
  68.     TskList(): cObj(0), pHead(0), pTail(0)
  69.         { }
  70.         
  71.      int    count()
  72.          { return cObj; }
  73.      void   append(TskObj *o);
  74.      TskObj *first()
  75.          { return pHead; }
  76.          
  77. };
  78.  
  79. class Sema; //  establish the name
  80. class Task; //  establish the name
  81.  
  82. class Scheduler {
  83. private:
  84.  
  85.     TskList     semas;              //  list of semas
  86.     TskList     tasks;              //  list of tasks
  87.     Task        *pTask;             //  the current task
  88.         
  89.     jmp_buf     schEnv;             //  environment in scheduler
  90.  
  91.     void        runATask();         //  try to run one task: return
  92.                                     //  if we are deadlocked
  93.     Sema        *findSema(uchar *sname);    //  look up sema in semas
  94.  
  95. public:
  96.  
  97.     Scheduler(): pTask(0)
  98.         { }
  99.  
  100.     void        endProcess()
  101.         {   longjmp(schEnv, -1); }
  102.     void        giveUpTask()
  103.         {   longjmp(schEnv, 1); }
  104.     void        addTask(Task *t);   //  inline, but later
  105.     
  106.     void        run();
  107.  
  108.     void        addSema(Sema *s);   //  inline, but later
  109.     void        signalSema(uchar *sname, Task *t, int units = 1);
  110.     void        waitSema(uchar *sname, Task *t);
  111.     
  112. };
  113.  
  114. class Sema: public TskObj {
  115. private:    
  116.  
  117.     uchar   *sName;         //  name of semaphore
  118.     int     value;          //  > 0 means task can wake up
  119.     Task    *tskWaiting;    //  what task is waiting on it
  120.     
  121. public:
  122.  
  123.     Sema(uchar *semaName): sName(semaName), value(0), tskWaiting(0)
  124.         { }
  125.     ~Sema()
  126.         { }
  127.  
  128.     uchar   *name()
  129.         { return sName; }
  130.         
  131.     void    signal(Task *t, int units = 1);
  132.     void    wait(Task *t);
  133. };
  134.  
  135. class Task: public TskObj {
  136. private:
  137.  
  138.     uint        ready: 1;   //  can task run?
  139.         
  140.     uchar       *tName;     //  name of task
  141.     const int   stkLen;     //  stack size
  142.     jmp_buf     tskEnv;     //  for context switching
  143.     Scheduler   &owner;     //  who controls this task
  144.     uchar far   *stack;     //  local stack for task
  145.     
  146. public:
  147.  
  148.     Task(uchar *name, Scheduler &s, int len = 0x1000);
  149.     virtual     ~Task();
  150.  
  151.     int         isReady()
  152.         { return ready; }
  153.     void        makeReady()
  154.         { ready = 1; }
  155.     void        makeWait()
  156.         { ready = 0; }
  157.  
  158.     uchar       *name()
  159.         { return tName; }
  160.  
  161.     int         isInited()
  162.         { return stack != 0; }
  163.     void        init();             //  never returns
  164.     virtual void    tskMain() = 0;  //  must derive a class to use this
  165.  
  166.     void        suspend();          //  give up to scheduler
  167.     void        resume();           //  wake up and continue right after
  168.                                     //  last call to suspend()
  169.     void        endProcess()        //  make the scheduler return 
  170.         { owner.endProcess(); }
  171.         
  172.     void        addSema(Sema *s)
  173.         { owner.addSema(s); }
  174.     void        signalSema(uchar *semaName, int units = 1)
  175.         { owner.signalSema(semaName, this, units); }
  176.     void        waitSema(uchar *semaName)
  177.         { owner.waitSema(semaName, this); }
  178.         
  179. };
  180.  
  181. inline void Scheduler::addSema(Sema *s)
  182.     { semas.append(s); }
  183.  
  184. inline void Scheduler::addTask(Task *t)
  185.     { tasks.append(t); }
  186.     
  187.  
  188. #endif
  189.